const Pokers = require("./Pokers");

class Game extends Pokers {
  constructor(players,socket) {
    super();  //继承自扑克牌对象
    this.players = players; //接收玩家数组
    this.socket = socket; //接收socket对象
    this.cardsArr = []; //存储玩家出过的牌
    this.cards = null; //存储当前出的牌
    this.roundCount = 0; //回合制计数，出牌次数
    this.startGame();
  }
  // 开局
  async startGame() {
    const _this = this;
    const [player1, player2, player3, player4] = this.players; //解构出四个玩家对象
    this.upset(); //洗牌
    // 遍历玩家，对每个玩家操作(触发每个玩家自带的方法)
    this.players.forEach(async (player, index) => {
      let pokers = _this.sysLicensing(7); //系统切牌
      player.order = index + 1; //出牌顺序
      player.initPlayState(); //初始化玩家状态
      player.licensing(pokers, player); //发牌
      // 第一位玩家先出牌
      if (player.order === 1) {
        player.firstFlag = true;
      }
    })
    this.sysLicensingStatus(player1, player2, player3, player4);
    await this.round(); //开始回合制
  }
  // 回合制
  async round() {
    // this.socket.on("playCard",data=>{
      
    // })
    return new Promise((resolve, reject) => {
      // 需要监听的属性，firstFlag,flag
      const _this = this;
      const [player1, player2, player3, player4] = this.players; //解构出四个玩家对象
      let awaitCount = 0; //等待对局结束的玩家个数
      let awaitGame = 0; //等待对局结束的玩家个数

      this.players.forEach(async player => {
        if (player.firstFlag) {
          player.flag = true;
          player.chupai();
        }
        await player.playCards()
      })

      // 监听系统牌的长度，如果长度为空返回结果
      Object.defineProperties(_this, {
        // 扑克牌
        "pokers": {
          set(val) {
            this.pokers = val; //赋值
            // let endGame = val.length == 0 && player1.pokers.length == 0 && player2.pokers.length == 0 && player3.pokers.length == 0 && player4.pokers.length == 0;
            // 结束对局标志：系统没有牌并且等待对局结束的玩家个数为3
            let endGame = val.length == 0 && awaitGame == 3;
            if (endGame) {
              resolve("对局结束！");
            }
          }
        },
        // 出牌次数
        "roundCount": {
          set(val) {
            roundCount = val; //赋值
            if (val % 4 === 0) {
              // 发牌状态
              this.sysLicensingStatus(player1, player2, player3, player4);
            }
          }
        }
      })

      // 监听对象属性
      // 玩家1
      Object.defineProperties(player1, {
        "firstFlag": {
          async set(val) {
            this.firstFlag = val; //赋值
            if (val) {
              _this.cards = await this.playCards(); //执行玩家的出牌方法
              _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
            }
          }
        },
        "flag": {
          async set(val) {
            console.log(11);
            this.flag = val; //赋值
            this.chuguopai = false; //是否出过牌
            //其他人都过牌，轮空、完成一个回合制，该玩家重新出牌
            let check = this.flag && player2.check && player3.check && player4.check;
            // 其他玩家没有过牌，并且自己轮到自己出牌，手里牌已经没有了并且系统牌不为空，就可以发牌
            let nullCards = this.flag && this.pokers.length == 0 && _this.pokers.length != 0 || !player2.check || !player3.check || !player4.check;
            // 玩家手中没有牌，系统牌也空了，就该等待对局结束
            let awaitGame = this.pokers.length == 0 && _this.pokers.length == 0;

            // 玩家赢了，等待对局结束，不用往下执行
            if (awaitGame) {
              awaitCount++;  //加入等待列表
              return this.awaitGameEnd();  //等待对局结束
            }

            if (val) {
              // 回合制，开始发牌，补牌
              if (check) {
                _this.players.forEach(async player => {
                  if (player.pokers.length == 7) return; //如果玩家手里有七张牌，就不用发牌
                  let leng = 7 - player.pokers.length; //需要发几张牌
                  let pokers = _this.sysLicensing(leng); //系统切牌
                  player.licensing(pokers, player)
                })
                _this.cards = await this.playCards(_this.cards, check); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
              }
              // 轮到玩家出牌，手里牌是空的，系统发牌，补牌
              else if (nullCards) {
                let pokers = _this.sysLicensing(7); //系统切牌
                player.licensing(pokers, player)
              }
              // 正常出牌
              else {
                _this.cards = await this.playCards(_this.cards); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
                // 出牌广播
                _this.players.forEach(player => {
                  player.sysPlayCards(_this.cards);
                })
              }
              if (this.chupai) {
                this.flag = false; //设置自身状态为false
                player2.flag = true; //触发下一个玩家出牌
                _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
              }
            }
          }
        }
      })
      // 玩家2
      Object.defineProperties(player2, {
        "firstFlag": {
          async set(val) {
            this.firstFlag = val; //赋值
            if (val) {
              _this.cards = await this.playCards(); //执行玩家的出牌方法
              _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
            }
          }
        },
        "flag": {
          async set(val) {
            console.log(11);
            this.flag = val; //赋值
            this.chuguopai = false; //是否出过牌
            //其他人都过牌，轮空、完成一个回合制，该玩家重新出牌
            let check = this.flag && player1.check && player3.check && player4.check;
            // 其他玩家没有过牌，并且自己轮到自己出牌，手里牌已经没有了并且系统牌不为空，就可以发牌
            let nullCards = this.flag && this.pokers.length == 0 && _this.pokers.length != 0 || !player1.check || !player3.check || !player4.check;
            // 玩家手中没有牌，系统牌也空了，就该等待对局结束
            let awaitGame = this.pokers.length == 0 && _this.pokers.length == 0;

            // 玩家赢了，等待对局结束，不用往下执行
            if (awaitGame) {
              awaitCount++;  //加入等待列表
              return this.awaitGameEnd();  //等待对局结束
            }

            if (val) {
              // 回合制，开始发牌，补牌
              if (check) {
                _this.players.forEach(async player => {
                  if (player.pokers.length == 7) return; //如果玩家手里有七张牌，就不用发牌
                  let leng = 7 - player.pokers.length; //需要发几张牌
                  let pokers = _this.sysLicensing(leng); //系统切牌
                  player.licensing(pokers, player)
                })
                _this.cards = await this.playCards(_this.cards, check); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
              }
              // 轮到玩家出牌，手里牌是空的，系统发牌，补牌
              else if (nullCards) {
                let pokers = _this.sysLicensing(7); //系统切牌
                player.licensing(pokers, player)
              }
              // 正常出牌
              else {
                _this.cards = await this.playCards(_this.cards); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
                _this.players.forEach(player => {
                  player.sysPlayCards(_this.cards);
                })
              }
              if (_this.cards) {
                this.flag = false; //设置自身状态为false
                player3.flag = true; //触发下一个玩家出牌
                _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
              }
            }
          }
        }
      })
      // 玩家3
      Object.defineProperties(player3, {
        "firstFlag": {
          async set(val) {
            this.firstFlag = val; //赋值
            if (val) {
              _this.cards = await this.playCards(); //执行玩家的出牌方法
              _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
            }
          }
        },
        "flag": {
          async set(val) {
            console.log(11);
            this.flag = val; //赋值
            this.chuguopai = false; //是否出过牌
            //其他人都过牌，轮空、完成一个回合制，该玩家重新出牌
            let check = this.flag && player1.check && player2.check && player4.check;
            // 其他玩家没有过牌，并且自己轮到自己出牌，手里牌已经没有了并且系统牌不为空，就可以发牌
            let nullCards = this.flag && this.pokers.length == 0 && _this.pokers.length != 0 || !player1.check || !player2.check || !player4.check;
            // 玩家手中没有牌，系统牌也空了，就该等待对局结束
            let awaitGame = this.pokers.length == 0 && _this.pokers.length == 0;

            // 玩家赢了，等待对局结束，不用往下执行
            if (awaitGame) {
              awaitCount++;  //加入等待列表
              return this.awaitGameEnd();  //等待对局结束
            }

            if (val) {
              // 回合制，开始发牌，补牌
              if (check) {
                _this.players.forEach(async player => {
                  if (player.pokers.length == 7) return; //如果玩家手里有七张牌，就不用发牌
                  let leng = 7 - player.pokers.length; //需要发几张牌
                  let pokers = _this.sysLicensing(leng); //系统切牌
                  player.licensing(pokers, player)
                })
                _this.cards = await this.playCards(_this.cards, check); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
              }
              // 轮到玩家出牌，手里牌是空的，系统发牌，补牌
              else if (nullCards) {
                let pokers = _this.sysLicensing(7); //系统切牌
                player.licensing(pokers, player)
              }
              // 正常出牌
              else {
                _this.cards = await this.playCards(_this.cards); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
                _this.players.forEach(player => {
                  player.sysPlayCards(_this.cards);
                })
              }
              if (_this.cards) {
                this.flag = false; //设置自身状态为false
                player4.flag = true; //触发下一个玩家出牌
                _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
              }
            }
          }
        }
      })
      // 玩家4
      Object.defineProperties(player4, {
        "firstFlag": {
          async set(val) {
            this.firstFlag = val; //赋值
            if (val) {
              _this.cards = await this.playCards(); //执行玩家的出牌方法
              _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
            }
          }
        },
        "flag": {
          async set(val) {
            console.log(11);
            this.flag = val; //赋值
            this.chuguopai = false; //是否出过牌
            //其他人都过牌，轮空、完成一个回合制，该玩家重新出牌
            let check = this.flag && player1.check && player2.check && player3.check;
            // 其他玩家没有过牌，并且自己轮到自己出牌，手里牌已经没有了并且系统牌不为空，就可以发牌
            let nullCards = this.flag && this.pokers.length == 0 && _this.pokers.length != 0 || !player1.check || !player2.check || !player3.check;
            // 玩家手中没有牌，系统牌也空了，就该等待对局结束
            let awaitGame = this.pokers.length == 0 && _this.pokers.length == 0;

            // 玩家赢了，等待对局结束，不用往下执行
            if (awaitGame) {
              awaitCount++;  //加入等待列表
              return this.awaitGameEnd();  //等待对局结束
            }

            if (val) {
              // 回合制，开始发牌，补牌
              if (check) {
                _this.players.forEach(async player => {
                  if (player.pokers.length == 7) return; //如果玩家手里有七张牌，就不用发牌
                  let leng = 7 - player.pokers.length; //需要发几张牌
                  let pokers = _this.sysLicensing(leng); //系统切牌
                  player.licensing(pokers, player)
                })
                _this.cards = await this.playCards(_this.cards, check); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
              }
              // 轮到玩家出牌，手里牌是空的，系统发牌，补牌
              else if (nullCards) {
                let pokers = _this.sysLicensing(7); //系统切牌
                player.licensing(pokers, player)
              }
              // 正常出牌
              else {
                _this.cards = await this.playCards(_this.cards); //执行玩家的出牌方法
                this.chuguopai = true; //是否出过牌
                _this.players.forEach(player => {
                  player.sysPlayCards(_this.cards);
                })
              }
              if (_this.cards) {
                this.flag = false; //设置自身状态为false
                player2.flag = true; //触发下一个玩家出牌
                _this.cardsArr.push(_this.cards); //将出过的牌放入数组存起来
              }
            }
          }
        }
      })

    });
  }
  // 定胜负
  referee() {

  }
  // 结束对局
  endGame() {

  }
  // 系统发牌状态
  async sysLicensingStatus(player1, player2, player3, player4) {
    await player1.cardsCount([
      { order: player1.order, pokers: player1.pokers },
      { order: player2.order, pokers: player2.pokers.length },
      { order: player3.order, pokers: player3.pokers.length },
      { order: player4.order, pokers: player4.pokers.length },
    ])
    // 状态
    await player2.cardsCount([
      { order: player2.order, pokers: player2.pokers },
      { order: player3.order, pokers: player3.pokers.length },
      { order: player4.order, pokers: player4.pokers.length },
      { order: player1.order, pokers: player1.pokers.length },
    ])
    // 状态
    await player3.cardsCount([
      { order: player3.order, pokers: player3.pokers },
      { order: player4.order, pokers: player4.pokers.length },
      { order: player1.order, pokers: player1.pokers.length },
      { order: player2.order, pokers: player2.pokers.length },
    ])
    // 状态
    await player4.cardsCount([
      { order: player4.order, pokers: player4.pokers },
      { order: player1.order, pokers: player1.pokers.length },
      { order: player2.order, pokers: player2.pokers.length },
      { order: player3.order, pokers: player3.pokers.length },
    ])
  }
}

module.exports = Game;